package com.tanhua.server.service;

//import com.tanhua.autoconfig.template.SmsTemplate;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.commons.utils.JwtUtils;
import com.tanhua.dubbo.api.UserApi;
import com.tanhua.dubbo.api.UserLikeApi;
import com.tanhua.model.domain.User;
import com.tanhua.model.mongo.UserLike;
import com.tanhua.model.vo.CountVO;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.server.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.*;

@Service
@Slf4j
public class UserService {//该UserService只在当前工程有用，故没必要创建接口了

//    @Autowired
//    private SmsTemplate template;

    private final String CHECKCODE="CHECK_CODE_";

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @DubboReference
    private UserApi userApi;

    @DubboReference
    private UserLikeApi userLikeApi;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    //发送短信验证码
    public void sendMsg(String phone) {
        //1. 随机生成6位数字
//        String code = RandomStringUtils.randomNumeric(6);
        String code="123456"; //为了测试方便，将验证码固定
/*        //2. 调用template对象,发送手机短信
        template.sendSms(phone,code);*/
        //2. 模拟发送验证码，将验证码输出到控制台
//        log.info("code={}",code);
        //3. 将验证码存入到redis,5分钟内有效
        redisTemplate.opsForValue().set(CHECKCODE+phone,code, Duration.ofMinutes(5));
    }


    /**
     * 验证登录
     * @param phone
     * @param code
     */
    public Map loginVerification(String phone, String code) {
        //1. 从redis中获取下发的验证码
        String redisCode = redisTemplate.opsForValue().get(CHECKCODE + phone);

        //2. 对验证码进行校验（验证码是否存在，是否和输入的验证码一致）
        if (StringUtils.isEmpty(redisCode) || !redisCode.equals(code)){
            //验证码无效
//            throw new RuntimeException("验证码错误");
            throw new BusinessException(ErrorResult.loginError());
        }

        //3. 删除redis中的验证码
        redisTemplate.delete(CHECKCODE+phone);

        //4. 通过手机号码查询用户
        User user = userApi.findByMobile(phone);
        boolean isNew = false;

        //5. 如果用户不存在，创建用户保存到数据库中
        if (user==null){
            user=new User();
            user.setMobile(phone);
            user.setPassword(DigestUtils.md5Hex("123456"));
            Long userId = userApi.save(user);
            user.setId(userId);
            isNew = true;

            //注册环信用户
            String hxUser = "hx"+user.getId();
            Boolean creat = huanXinTemplate.createUser(hxUser, Constants.INIT_PASSWORD);
            if (creat){
                user.setHxUser(hxUser);
                user.setHxPassword(Constants.INIT_PASSWORD);
                userApi.update(user);
            }
        }
        //6. 通过JWT生成token(存入id和手机号码)
        Map tokeMap=new HashMap();
        tokeMap.put("id",user.getId());
        tokeMap.put("mobile",phone);
        String token = JwtUtils.getToken(tokeMap);
        //7. 构造返回值
        Map retMap=new HashMap();
        retMap.put("token",token);
        retMap.put("isNew",isNew);

        return retMap;
    }

    public CountVO counts(Long userId) {

        //统计用户喜欢的数量（直接通过redis查询）
        String key = Constants.USER_LIKE_KEY+userId;
        Set<String> members = redisTemplate.opsForSet().members(key);
        Integer loveCount = members.size();
        //统计互相喜欢的数量
        Integer eachLoveCount = 0;
        for (String member : members) {
            //如果喜欢的用户，也喜欢自己
            if (isLike(Long.valueOf(member),userId)){
                eachLoveCount++;
            }
        }
        //统计用户粉丝的数量（调用api通过mongo数据库查询）
        Integer fanCount = userLikeApi.counts(userId);

        //构造CountVo对象进行返回
        CountVO vo =new CountVO(eachLoveCount,loveCount,fanCount);
        return vo;
    }
    //判断用户是否喜欢另一个用户
    public Boolean isLike(Long userId,Long likeUserId){
        String key = Constants.USER_LIKE_KEY+userId;
        return redisTemplate.opsForSet().isMember(key,likeUserId.toString());
    }
}
